﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Nirvana
{
    /// <summary>
    /// 某区域音效
    /// </summary>
    [AddComponentMenu("Nirvana/Audio/Area Audio")]
    public sealed class AreaAudio : MonoBehaviour
    {
        private static Logger logger = LogSystem.GetLogger("AreaAudio");

        [SerializeField]
        [AssetType(typeof(AudioItem))]
        [Tooltip("The ambiance SFX.")]
        private AssetID audioAsset;
        private AudioItem audioitem;
        private IBasicAudio audioplayer;
        private bool IsPlaying = false;

        private Transform audioSourceNode;
        private AudioListener audioListener;
        private Collider[] colliders;

        private void Update()
        {
            if (audioListener == null) return;
            Vector3 pos = audioListener.transform.position;
            float minDist = float.PositiveInfinity;
            Vector3 minPos = Vector3.zero;
            for(int i=0,imax = colliders.Length; i < imax; i++)
            {
                Vector3 cloestPos = colliders[i].ClosestPointOnBounds(pos);
                float dist = (cloestPos - pos).sqrMagnitude;
                if(minDist > dist)
                {
                    minDist = dist;
                    minPos = cloestPos;
                }
            }
            this.audioListener.transform.position = minPos;
        }


        private void OnEnable()
        {
            if (!this.IsPlaying && !this.audioAsset.IsEmpty && this.audioplayer == null)
            {
                StartCoroutine(Play());
            }
        }
        private void OnDisable()
        {
            Stop();
        }

        private IEnumerator Play()
        {
            this.IsPlaying = true;
            WaitLoadScriptable waitLoadScriptable = ScriptablePool.Instance.Load(this.audioAsset);
            yield return waitLoadScriptable;
            if (!string.IsNullOrEmpty(waitLoadScriptable.Error))
            {
                logger.LogError("PlayAndForget {0} failed: {1}", this.audioAsset, waitLoadScriptable.Error);
                yield break;
            }

            this.audioListener = FindObjectOfType<AudioListener>();
            if (this.audioListener == null) yield break;
            this.colliders = GetComponents<Collider>();
            if(this.audioSourceNode == null)
            {
                this.audioSourceNode = new GameObject("Audio Source").transform;
                this.audioSourceNode.parent = this.transform;
            }


            this.audioitem = waitLoadScriptable.LoadedObject as AudioItem;
            this.audioplayer = AudioManager.Play(this.audioitem);
            yield return this.audioplayer.WaitFinish();
            ScriptablePool.Instance.Free(this.audioitem, false);
            this.audioplayer = null;
        }
        private void Stop()
        {
            this.IsPlaying = false;
            StopAllCoroutines();
            if (this.audioplayer != null)
            {
                this.audioplayer.Stop();
                this.audioplayer = null;
            }
            if (this.audioitem != null)
            {
                ScriptablePool.Instance.Free(this.audioitem, false);
                this.audioitem = null;
            }
        }

    }
}

